package util;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * Clase encargada de facilitar la inicializaci&oacute;n del registro RMI y la publicaci&oacute;n de objetos.
 * @author Globex Inc.
 *
 */
public class AgregadorRMI {
	static Registry _registry;
	
	/**
	 * Inicializa el registro en un puerto. 
	 * @param port puerto donde se inicia el registro.
	 * @return true si se ha publicado correctamente y false en caso contrario.
	 * @throws RemoteException
	 */
	public static boolean iniciarRegistro(int port) throws RemoteException {
		boolean ans = false;
		try {
			// if it exist then get it
			_registry = LocateRegistry.getRegistry(port);
			_registry.list(); // dunno why, but this is needed
			//System.out.println("Using existing registry");
			ans = true;
		} catch (RemoteException ex) {
			// doesn't exist so create it
			//System.out.println("RMI registry cannot be located at port " + port);
			_registry = LocateRegistry.createRegistry(port);
			ans = true;
			//System.out.println("RMI registry created at port " + port);
		}
		
		return ans;
	}
	
	/**
	 * Obtiene el registro publicado en un puerto de una determinada m&aacute;quina.
	 * @param host Identificacor de la m&aacute;quina.
	 * @param port Puerto donde se ha inicializado el servidor RMI
	 * @return true si se ha podido obtener y false en caso contrario.
	 */
	public static boolean obtenerRegistro(String host, int port) {
		try {
			// if it exist then get it
			_registry = LocateRegistry.getRegistry(host, port);
			return true;
		} catch (RemoteException ex) {
			// not found
			System.out.println("RMI registry cannot be located at "+host+":"+port);
			return false;
		}
	}
	
	/**
	 * Devuelve el n&uacute;mero de objetos registrados.
	 * @return n&uacute;mero de objetos registrados.
	 */
	public static int contarRegistrados(){
		try {
			return _registry.list().length;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}
	
	/**
	 * Muestra por pantalla los registros diponibles.
	 */
	public static void listar() {
		try {
			for(String str: _registry.list( ))
				System.out.println(str);
		} catch (RemoteException ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * Agrega un objetro al registro local.
	 * @param obj Objetor a agregar.
	 * @param id Ruta donde se va a publicar el objeto.
	 * @param puerto Puerto donde se ha inicializado el registro RMI.
	 * @throws MalformedURLException
	 * @throws RemoteException
	 */
	public static void agregar(UnicastRemoteObject obj, String id, int puerto) throws MalformedURLException, RemoteException {
		Naming.rebind("//localhost:"+puerto+"/"+id, obj);
	}
	
	/**
	 * Obtiene un objeto remoto publicado en un servidor.
	 * @param servidor URL del servidor.
	 * @param puerto Puerto RMI donde se ha publicado el objeto.
	 * @param id Ruta del objeto.
	 * @return EL objeto obetnido.
	 * @throws MalformedURLException
	 * @throws NotBoundException
	 * @throws RemoteException
	 */
	public static Remote obtenerRemoto(String servidor, int puerto, String id) throws MalformedURLException, NotBoundException, RemoteException{
		return Naming.lookup("//"+servidor+":"+puerto+"/"+id);
	}
}
